﻿using System;
using System.Collections.Generic;
using System.Configuration;

using ApplicationBoilerplate.DataProvider;
using ApplicationBoilerplate.DependencyInjection;

using MongoDB.Driver;

namespace MVCBootstrap.MongoDB.DependencyInjection {

	public class DataProviderBuilder : IDependencyBuilder {
		protected MongoDatabase database;
		private Boolean sideBySide = false;
		private String connectionName = String.Empty;

		public DataProviderBuilder()
			: this(false, String.Empty) {
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sideBySide">If you're running MongoDB alongside another MVC Bootstrap data provider, this must be true.</param>
		public DataProviderBuilder(Boolean sideBySide)
			: this(sideBySide, String.Empty) {
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sideBySide">If you're running MongoDB alongside another MVC Bootstrap data provider, this must be true.</param>
		/// <param name="connectionName"></param>
		public DataProviderBuilder(Boolean sideBySide, String connectionName) {
			this.sideBySide = sideBySide;
			this.connectionName = String.IsNullOrWhiteSpace(connectionName) ? "DataProvider.MongoDB" : connectionName;
		}

		public virtual void Configure(IDependencyContainer container) {
			String connectionString = ConfigurationManager.ConnectionStrings[this.connectionName].ConnectionString;

			Connection conn = new Connection(connectionString);
			container.RegisterSingleton<IConnection>(conn);
			container.RegisterGeneric(typeof(IMongoCollection<>), typeof(Collection<>));

			if (!this.sideBySide) {
				// No other data provider in use, so we'll register the "core" interfaces!!
				container.RegisterSingleton<IContext>(conn);
				container.RegisterGeneric(typeof(IRepository<>), typeof(Repository<>));
			}

			MongoUrl url = MongoUrl.Create(connectionString);
			String databaseName = url.DatabaseName;
			MongoClient client = new MongoClient(url);
			MongoServer server = client.GetServer();
			this.database = server.GetDatabase(databaseName);

			MongoCollection mongoCollection = this.database.GetCollection(typeof(User).Name.ToLowerInvariant());
			mongoCollection.EnsureIndex(UserFieldNames.ApplicationName);
			mongoCollection.EnsureIndex(UserFieldNames.ApplicationName, UserFieldNames.Email);
			mongoCollection.EnsureIndex(UserFieldNames.ApplicationName, UserFieldNames.UpperUsername);

			mongoCollection = this.database.GetCollection(typeof(Role).Name.ToLowerInvariant());
			mongoCollection.EnsureIndex(RoleFieldNames.ApplicationName);
			mongoCollection.EnsureIndex(RoleFieldNames.ApplicationName, RoleFieldNames.RoleName);

			//mongoCollection = this.database.GetCollection(typeof(TextChunk).Name.ToLowerInvariant());
			//mongoCollection.Insert<TextChunk>(new TextChunk {
			//    Namespace = "Navigation.TopNavigation",
			//    Texts = new List<Text> {
			//        new Text {
			//            Key = "Home.Index",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "Home"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Hjem"
			//                }
			//            }
			//        },
			//        new Text {
			//            Key = "Home.About",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "About"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Om"
			//                }
			//            }
			//        },
			//        new Text {
			//            Key = "Account.ChangePassword",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "Change Password"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Skift kodeord"
			//                }
			//            }
			//        }
			//    }
			//});
			//mongoCollection.Insert<TextChunk>(new TextChunk {
			//    Namespace = "CommonTexts",
			//    Texts = new List<Text> {
			//        new Text {
			//            Key = "Title",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "My MVC Application"
			//                },
			//                new Translation {
			//                    Language = "Min MVC applikation",
			//                    Text = "Hjem"
			//                }
			//            }
			//        },
			//        new Text {
			//            Key = "WelcomeText",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "Welcome {Username}"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Velkommen {Username}"
			//                }
			//            }
			//        },
			//        new Text {
			//            Key = "LogOffText",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "Log Off"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Log af"
			//                }
			//            }
			//        },
			//        new Text {
			//            Key = "LogOnText",
			//            Texts = new List<Translation> {
			//                new Translation {
			//                    Language = "en-GB",
			//                    Text = "Log On"
			//                },
			//                new Translation {
			//                    Language = "da-DK",
			//                    Text = "Log på"
			//                }
			//            }
			//        }
			//    }
			//});
		}

		public virtual void ValidateRequirements(IList<ApplicationRequirement> feedback) {
			if (ConfigurationManager.ConnectionStrings[this.connectionName] == null) {
				feedback.Add(new ApplicationRequirement {
					Feedback = @"No connection found for the application, please insert this into the application's web.config file:

<configuration>
	<connectionStrings>
		<add name=""" + this.connectionName + @"""
			connectionString=""mongodb://localhost""
		/>
	</connectionStrings>
</configuration>

Remember to replace the values in the connection string with values that matches your set-up.
",
					Level = RequirementLevel.Fatal
				});
			}
			else {
				feedback.Add(new ApplicationRequirement { Feedback = "Connection string for the application located.", Level = RequirementLevel.Info });
			}
		}
	}
}